﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using Kaskelot.SP.Model.Client;
using Kaskelot.SP.Model.Client.Forms;
using Kaskelot.SP.Services.Client.Mapping;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using Kaskelot.SP.Core;
using Microsoft.SharePoint;

namespace Kaskelot.SP.Services.Client
{
	[ServiceContract(Namespace = "http://Kaskelot.SP.Services")]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class ClientBemanningService
	{
		#region Bemanna
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<PersonSearchResult>> BemanningPersonSearch(string namn, string personnummer, string postnummer, string fritext, string funktionId, bool visaInaktiva, bool visaGrupp, bool visaValdistrikt, string typ)
		{
			ClientServiceResult<IEnumerable<PersonSearchResult>> csr = new ClientServiceResult<IEnumerable<PersonSearchResult>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					PersonSearchParameters parameters = new PersonSearchParameters();

					parameters.Namn = namn;
					parameters.Personnummer = personnummer;
					parameters.Postnummer = postnummer;
					parameters.Fritext = fritext;
					parameters.VisaInaktiva = visaInaktiva;
					parameters.TypId = typ.IsGuid() ? (Guid?)new Guid(typ) : null;
					parameters.VisaBemannadGrupp = visaGrupp;
					parameters.VisaBemannadValdistrikt = visaValdistrikt;
					if (funktionId.IsGuid())
					{
						parameters.FunktionId = new Guid(funktionId);
					}

					csr.Data = svc.BemanningSearchPersoner(parameters);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> BemannaVakans(BemannaForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (form.VakansId.IsGuid() && form.PersonId.IsGuid())
					{
						bool removeExisting = false;
						if (!bool.TryParse(form.RemoveExisting, out removeExisting))
						{
							// Kontrollera existerande uppdrag
							var uppdrag = svc.GetBemanningByPersonId(new Guid(form.PersonId));

							if (uppdrag.Any(u => u.UppdragVal == ApplicationContext.Current.Val.Namn))
							{
								using (PersonService pSvc = new PersonService())
								{
									Person p = pSvc.GetPerson(new Guid(form.PersonId));
									string personInfo = string.Format("{0} {1} ({2})", p.Fornamn, p.Efternamn, p.Personnummer);
									string uppdragsinfo = string.Join("<br />", uppdrag.Where(u => u.UppdragVal == ApplicationContext.Current.Val.Namn).Select(pu => string.Format("{0} - {1}", pu.UppdragFunktion, pu.UppdragNamn)).ToArray());

									csr.WarningMessage = string.Format("{0} är redan placerad i följande uppdrag:<br /><br />{1}<br /><br />Om du fortsätter kommer detta uppdrag i annat valdistrikt att tas bort.<br />Uppdrag i grupper påverkas inte.", personInfo, uppdragsinfo);
									csr.HasWarning = true;
								}
							}
							else
								svc.BemannaVakans(new Guid(form.VakansId), new Guid(form.PersonId), removeExisting);
						}
						else
						{
							svc.BemannaVakans(new Guid(form.VakansId), new Guid(form.PersonId), removeExisting);
						}
					}
					else
						throw new Exception();
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Bemanning av vakans misslyckades.";
				csr.HasError = true;
			}

			return csr;
		}
		#endregion

		#region Sökningar
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<VakansSearchResult>> VakansSearch(string valkretsId, string forsamlingId, string valdistriktId, string funktionId)
		{
			ClientServiceResult<IEnumerable<VakansSearchResult>> csr = new ClientServiceResult<IEnumerable<VakansSearchResult>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					VakansSearchParameters vsp = new VakansSearchParameters();
					if (valkretsId.IsGuid())
						vsp.ValkretsId = new Guid(valkretsId);
					if (forsamlingId.IsGuid())
						vsp.ForsamlingId = new Guid(forsamlingId);
					if (valdistriktId.IsGuid())
						vsp.ValdistriktId = new Guid(valdistriktId);
					if (funktionId.IsGuid())
						vsp.FunktionId = new Guid(funktionId);

					csr.Data = svc.VakansSearch(vsp).OrderBy(v => v.ValkretsNamn).ThenBy(v => v.ForsamlingNamn).ThenBy(v => v.ValdistriktNamn).ThenBy(v => v.FunktionNamn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ValdistriktSearchResult>> ValdistriktSearch(string valkretsId, string forsamlingId, string status, string kurstillfalleId)
		{
			ClientServiceResult<IEnumerable<ValdistriktSearchResult>> csr = new ClientServiceResult<IEnumerable<ValdistriktSearchResult>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					ValdistriktSearchParameters vsp = new ValdistriktSearchParameters();
					if (valkretsId.IsGuid())
						vsp.ValkretsId = new Guid(valkretsId);
					if (forsamlingId.IsGuid())
						vsp.ForsamlingId = new Guid(forsamlingId);
					if (kurstillfalleId.IsGuid())
						vsp.KursTillfalleId = new Guid(kurstillfalleId);

					var v = svc.ValdistriktSearch(vsp).OrderBy(vd => vd.ValkretsNamn).ThenBy(vd => vd.ForsamlingNamn).ThenBy(vd => vd.ValdistriktNamn);

					if (String.IsNullOrEmpty(status))
						csr.Data = v;
					else if (status.FromKlarEjKlar())
						csr.Data = v.Where(x => x.ValdistriktStatus == BoolExtensions.Klar);
					else
						csr.Data = v.Where(x => x.ValdistriktStatus == BoolExtensions.EjKlar);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientGrupp>> GruppSearch(string kursTillfalleId)
		{
			ClientServiceResult<IEnumerable<ClientGrupp>> csr = new ClientServiceResult<IEnumerable<ClientGrupp>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					List<Grupp> v;
					if (kursTillfalleId.IsGuid())
						v = svc.GruppSearch(new Guid(kursTillfalleId)).ToList();
					else
						v = svc.GruppSearch(null).ToList();

					foreach (var x in v)
					{
						var y = svc.GetGruppDetails(x.Id).BemanningGrupp;

						bool status = y.ToList().Count > 0;
						foreach (var z in y)
						{
							if (!z.TackatJa)
							{
								status = false;
								break;
							}
						}

						x.Status = status.ToKlarEjKlar();
					}

					csr.Data = v.Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}
		#endregion

		#region Valdistrikt
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<ValdistriktDetailsView> GetValdistriktDetails(string id)
		{
			ClientServiceResult<ValdistriktDetailsView> csr = new ClientServiceResult<ValdistriktDetailsView>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						csr.Data = svc.GetValdistriktDetails(new Guid(id));
						csr.Data.AndradAv = csr.Data.AndradAv.ToSharePointFullName();
						csr.Data.SkapadAv = csr.Data.SkapadAv.ToSharePointFullName();
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientBemanningValdistrikt>> GetBemanning(string id)
		{
			ClientServiceResult<IEnumerable<ClientBemanningValdistrikt>> csr = new ClientServiceResult<IEnumerable<ClientBemanningValdistrikt>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						csr.Data = svc.GetValdistriktDetails(new Guid(id)).BemanningValdistrikt.Select(bv => bv.ToClientContract()).OrderBy(bv => bv.FunktionNamn);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> RemovePersonFromBemanningValdistrikt(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						svc.RemovePersonFromBemanningValdistrikt(new Guid(id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteBemanningValdistrikt(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						svc.DeleteBemanningValdistrikt(new Guid(id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateBemanningValdistrikt(BemanningValdistriktForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (form.ValdistriktId.IsGuid() && form.FunktionId.IsGuid())
					{
						BemanningValdistrikt bv = new BemanningValdistrikt
						{
							SkapadAv = SPContext.Current.Web.CurrentUser.Name,
							Skapad = DateTime.Now,
							ValId = ApplicationContext.Current.Val.Id
						};

						bv.UpdateContract(form);
						svc.CreateBemanningValdistrikt(bv);
					}
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Bemanning av vakans misslyckades.";
				csr.HasError = true;
			}

			return csr;
		}
		#endregion

		#region Grupp
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<GruppDetailsView> GetGruppDetails(string id)
		{
			ClientServiceResult<GruppDetailsView> csr = new ClientServiceResult<GruppDetailsView>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						csr.Data = svc.GetGruppDetails(new Guid(id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientBemanningGrupp>> GetBemanningGrupp(string id)
		{
			ClientServiceResult<IEnumerable<ClientBemanningGrupp>> csr = new ClientServiceResult<IEnumerable<ClientBemanningGrupp>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						csr.Data = svc.GetGruppDetails(new Guid(id)).BemanningGrupp.Select(bv => bv.ToClientContract()).OrderBy(bv => bv.FunktionNamn).ThenBy(bv => bv.PersonNamn.IsNullOrEmpty()).ThenBy(bv => bv.PersonNamn);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> RemovePersonFromBemanningGrupp(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						svc.RemovePersonFromBemanningGrupp(new Guid(id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteBemanningGrupp(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						svc.DeleteBemanningGrupp(new Guid(id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateBemanningGrupp(BemanningGruppForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (form.GruppId.IsGuid() && form.FunktionId.IsGuid())
					{
						int antal = Int32.Parse(form.Antal);

						for (int i = 0; i < antal; i++)
						{
							BemanningGrupp bv = new BemanningGrupp
							{
								SkapadAv = SPContext.Current.Web.CurrentUser.Name,
								Skapad = DateTime.Now,
								ValId = ApplicationContext.Current.Val.Id
							};

							bv.UpdateContract(form);
							svc.CreateBemanningGrupp(bv);
						}
					}
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Åtgärden misslyckades.";
				csr.HasError = true;
			}

			return csr;
		}
		#endregion

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> ToggleBemanningGruppTackatJa(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						BemanningGrupp bv = svc.GetBemanningGrupp(new Guid(id));

						bv.TackatJa = !bv.TackatJa;
						bv.Andrad = DateTime.Now;
						bv.AndradAv = SPContext.Current.Web.CurrentUser.Name;

						svc.UpdateBemanningGrupp(bv);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> ToggleBemanningValdistriktTackatJa(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						BemanningValdistrikt bv = svc.GetBemanningValdistrikt(new Guid(id));

						bv.TackatJa = !bv.TackatJa;
						bv.Andrad = DateTime.Now;
						bv.AndradAv = SPContext.Current.Web.CurrentUser.Name;

						svc.UpdateBemanningValdistrikt(bv);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateErsattning(string id, string mil, string taxi)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					if (id.IsGuid())
					{
						BemanningValdistrikt bv = svc.GetBemanningValdistrikt(new Guid(id));

						if (mil.IsNonEmpty())
							bv.MilErsattning = Double.Parse(mil.Replace(".", ","));

						if (taxi.IsNonEmpty())
							bv.TaxiUtlagg = Double.Parse(taxi.Replace(".", ","));

						svc.UpdateBemanningValdistrikt(bv);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}
	}
}
